<template>
  <div class="tree-model-box">
    <div class="index-model" id="indexModelChar" :style="{ height: chartHeight, width: chartWidth }"></div>
    <div id="rightMenu" class="right-menu">
      <ul class="menu-box">
        <li :class="['menu-item', curNodeInfo.busType === '06' ? 'disabled' : '']" @click="onMenuClick('addNext')">
          添加下级指标/模型
        </li>
        <li :class="['menu-item', isRoot ? 'disabled' : '']" @click="onMenuClick('addSibling')">添加同级指标/模型</li>
        <li :class="['menu-item', isRoot ? 'disabled' : '']" @click="onMenuClick('copy')">复制并创建</li>
        <li :class="['menu-item', isRoot ? 'disabled' : '']" @click="onMenuClick('delete')">删除指标/模型</li>
      </ul>
    </div>
  </div>
</template>
<script>
import Echarts from '@libs/echarts'
export default {
  name: 'TreeModel',
  components: {},
  props: {
    source: {
      type: Object,
      default: () => {},
    },
  },
  emits: ['node-select', 'menu-click'],
  data() {
    return {
      treeData: {},
      curNodeInfo: {},
      treeChart: null,
      treeOption: {
        tooltip: {
          show: true,
          triggerOn: 'mousemove',
          formatter: function (params) {
            const { assessName, assessScore } = params.data || {}
            return `${assessName}（${assessScore}分）`
          },
        },
        series: [
          {
            type: 'tree',
            name: 'indexModel',
            id: 'indexModel',
            roam: true,
            symbol: 'none',
            zoom: 1,
            initialTreeDepth: -1, // 全部展开
            selectedMode: 'single',
            select: {
              label: {
                color: '#fff',
                backgroundColor: '#5593f4',
              },
            },
            data: [
              {
                busId: '1602932631439450112',
                assessName: '德',
                assessNum: 'LEADERSHIP-HF_TARGET_MOXVRT',
                assessDesc: '偏重品德考核的指标描述',
                assessScore: '15',
                assessExpand: '偏重品德考核的评价说明',
                busType: '06',
                weight: '',
                isRoot: 0,
                children: [],
              },
              {
                busId: '1602932638573961216',
                assessName: '能',
                assessNum: 'LEADERSHIP-HF_TARGET_MBHWPI',
                assessDesc: '',
                assessScore: '20',
                assessExpand: '',
                busType: '06',
                weight: '',
                isRoot: 0,
                children: [],
              },
              {
                busId: '1602932645037383680',
                assessName: '勤',
                assessNum: 'LEADERSHIP-HF_TARGET_HCRUCE',
                assessDesc: '',
                assessScore: '15',
                assessExpand: '',
                busType: '06',
                weight: '',
                isRoot: 0,
                children: [],
              },
              {
                busId: '1602932650854883328',
                assessName: '绩',
                assessNum: 'LEADERSHIP-HF_TARGET_XYBXET',
                assessDesc: '',
                assessScore: '20',
                assessExpand: '',
                busType: '06',
                weight: '',
                isRoot: 0,
                children: [],
              },
              {
                busId: '1602932657016315904',
                assessName: '廉',
                assessNum: 'LEADERSHIP-HF_TARGET_ALBTEO',
                assessDesc: '',
                assessScore: '20',
                assessExpand: '',
                busType: '06',
                weight: '',
                isRoot: 0,
                children: [],
              },
              {
                busId: '1603192988334596096',
                assessName: '体能',
                assessNum: 'LEADERSHIP-HF_MODEL_QZPBTW',
                assessDesc: '',
                assessScore: '5',
                assessExpand: '',
                busType: '05',
                weight: '',
                isRoot: 0,
                children: [
                  {
                    busId: '1603195683254607872',
                    assessName: '身体',
                    assessNum: 'LEADERSHIP-HF_TARGET_CXXAGB',
                    assessDesc: '',
                    assessScore: '3',
                    assessExpand: '',
                    busType: '06',
                    weight: '',
                    isRoot: 0,
                    children: [],
                  },
                  {
                    busId: '1603195837906984960',
                    assessName: '心理',
                    assessNum: 'LEADERSHIP-HF_TARGET_FNXGGN',
                    assessDesc: '心理健康',
                    assessScore: '2',
                    assessExpand: '',
                    busType: '06',
                    weight: '',
                    isRoot: 0,
                    children: [],
                  },
                ],
              },
              {
                busId: '1603212195457703936',
                assessName: '办事效率',
                assessNum: 'LEADERSHIP-HF_MODEL_XGXXIR',
                assessDesc: '',
                assessScore: '5',
                assessExpand: '',
                busType: '05',
                weight: '',
                isRoot: 0,
                children: [
                  {
                    busId: '1603212374269272064',
                    assessName: '办事质量',
                    assessNum: 'LEADERSHIP-HF_TARGET_AZOFXI',
                    assessDesc: '办事质量',
                    assessScore: '1',
                    assessExpand: '',
                    busType: '06',
                    weight: '',
                    isRoot: 0,
                    children: [],
                  },
                  {
                    busId: '1603212437334827008',
                    assessName: '办事数量',
                    assessNum: 'LEADERSHIP-HF_MODEL_ZALETK',
                    assessDesc: '办事数量',
                    assessScore: '4',
                    assessExpand: '',
                    busType: '05',
                    weight: '',
                    isRoot: 0,
                    children: [
                      {
                        busId: '1603212789442453504',
                        assessName: '指标1',
                        assessNum: 'LEADERSHIP-HF_TARGET_BSBHTI',
                        assessDesc: '指标1',
                        assessScore: '2',
                        assessExpand: '',
                        busType: '06',
                        weight: '',
                        isRoot: 0,
                        children: [],
                      },
                      {
                        busId: '1603212918522159104',
                        assessName: '指标2',
                        assessNum: 'LEADERSHIP-HF_TARGET_PSVSMH',
                        assessDesc: '',
                        assessScore: '2',
                        assessExpand: '',
                        busType: '06',
                        weight: '',
                        isRoot: 0,
                        children: [],
                      },
                    ],
                  },
                ],
              },
            ],
            top: 60,
            left: 120,
            bottom: 60,
            right: 120,
            label: {
              width: 120,
              height: 40,
              align: 'center',
              verticalAlign: 'middle',
              backgroundColor: '#e9eff4',
              padding: [5, 10],
              fontSize: 14,
              overflow: 'break',
              lineHeight: 24,
              formatter: params => {
                const { assessName = '', assessScore = 0 } = params.data || {}
                if (assessName.length > 10) {
                  return `${assessName.slice(0, 10)}...（${assessScore}分）`
                } else {
                  return `${assessName}（${assessScore}分）`
                }
              },
            },
            edgeShape: 'polyline', // 折线
            lineStyle: {
              color: '#5593f4',
            },
            emphasis: {
              // 移动鼠标不再高亮展示
              disabled: true,
            },
            animationDuration: 300,
            animationDurationUpdate: 350,
          },
        ],
      },
      offsetTop: 85,
      offsetLeft: 50,
      maxCol: 1,
      maxRow: 1,
    }
  },
  computed: {
    isRoot() {
      return String(this.curNodeInfo.isRoot) === '1'
    },
    chartWidth() {
      return this.maxCol > 3 ? (this.maxCol - 3) * 20 + 100 + '%' : '100%'
    },
    chartHeight() {
      return this.maxRow > 8 ? (this.maxRow - 8) * 20 + 100 + '%' : '100%'
    },
  },
  watch: {
    source: {
      handler(obj) {
        if (obj && obj.busId) {
          this.initChart()
        }
      },
      deep: true,
      immediate: true,
    },
  },
  beforeDestroy() {
    window.removeEventListener('resize', this.resizeTree)
    this.treeChart && this.treeChart.off('click', this.onNodeClick)
    document.getElementById('indexModelChar') &&
      document.getElementById('indexModelChar').removeEventListener('click', this.hideMenu)
    document.oncontextmenu = function (param) {
      return true
    }
  },
  beforeRouteLeave(to, from, next) {
    window.removeEventListener('resize', this.resizeTree)
    this.treeChart && this.treeChart.off('click', this.onNodeClick)
    document.getElementById('indexModelChar') &&
      document.getElementById('indexModelChar').removeEventListener('click', this.hideMenu)
    document.oncontextmenu = function (param) {
      return true
    }
    next()
  },
  mounted() {
    window.addEventListener('resize', this.resizeTree)
    document.oncontextmenu = function (param) {
      return false
    }
    document.getElementById('indexModelChar').addEventListener('click', this.hideMenu)
  },
  methods: {
    initData(data, n) {
      if (Array.isArray(data)) {
        this.maxRow = Math.max(this.maxRow, data.length)
        data.forEach(item => {
          this.initData(item, n)
        })
      } else if (typeof data === 'object') {
        data.value = Number(data.assessScore)
        data.name = data.busId || '' // 名字使用ID，保证选中节点的唯一性
        data.id = data.busId || ''
        if (data.children && data.children.length) {
          this.initData(data.children, n + 1)
        } else {
          this.maxCol = Math.max(this.maxCol, n)
          return data
        }
      }
      return data
    },
    initChart() {
      if (this.treeChart) {
        this.treeChart.clear()
        this.maxCol = 1
        this.maxRow = 1
      }
      this.$nextTick(() => {
        this.treeData = this.initData(this.source, 1)
        this.treeChart = Echarts.init(document.getElementById('indexModelChar'))
        this.drawEcharts()
      })
    },
    resizeTree() {
      this.treeChart && this.treeChart.resize()
    },
    drawEcharts() {
      this.treeOption.series[0].data = [this.treeData]
      this.treeChart.on('click', this.onNodeClick)
      if (this.$route.query.type !== 'view') {
        this.treeChart.on('contextmenu', this.showMenu)
      }
      setTimeout(() => {
        this.resizeTree()
      }, 2000)

      this.treeChart.setOption(this.treeOption)

      // 默认选中根节点
      this.treeChart.dispatchAction({
        type: 'select',
        seriesName: 'indexModel',
        seriesId: 'indexModel',
        dataIndex: 1,
      })
      this.curNodeInfo = this.treeData
    },
    onNodeClick(obj) {
      if (obj && obj.data) {
        if (obj.data.id !== this.curNodeInfo.busId) {
          this.$emit('node-select', obj.data, obj.data.id)
        }
        this.curNodeInfo = obj.data || {}
        this.treeChart.dispatchAction({
          type: 'select',
          seriesId: 'indexModel',
          dataIndex: obj.dataIndex,
        })
      }
    },
    showMenu(param) {
      if (this.$route.query.type === 'view') {
        return false
      }
      this.curNodeInfo = param.data || {}
      const rightMenu = document.getElementById('rightMenu')
      rightMenu.style = `display: block; left: ${param.event.offsetX + 15}px;top:${param.event.offsetY - 15}px;`
    },
    hideMenu() {
      const rightMenu = document.getElementById('rightMenu')
      rightMenu.style = 'display:none;left:-999px;top:-999px;'
    },
    // 添加输入框
    addInput() {
      const boxEl = document.querySelector('#indexModel>div')
      if (boxEl) {
        const inpEls = document.querySelectorAll('#indexModel .node-input-box')
        if (inpEls && inpEls.length) {
          for (let i = 0; i < inpEls.length; i++) {
            boxEl.removeChild(inpEls[i])
          }
        }
      }
      const model = this.treeChart.getModel().getSeriesByIndex(0).getData()
      const layouts = model._itemLayouts || []
      for (let i = 1; i < layouts.length; i++) {
        const inpBox = document.createElement('div')
        inpBox.classList.add('node-input-box')
        inpBox.style = `top:${this.offsetTop + Math.round(layouts[i].y)}px;left:${
          this.offsetLeft + Math.round(layouts[i].x)
        }px`

        const labelEl = document.createElement('label')
        labelEl.classList.add('inp-label')
        labelEl.innerText = '分值'
        inpBox.appendChild(labelEl)

        const inpEl = document.createElement('input')
        inpEl.type = 'number'
        inpEl.classList.add('node-input')
        inpBox.appendChild(inpEl)

        const spanEl = document.createElement('span')
        spanEl.classList.add('unit')
        spanEl.innerText = '分'
        inpBox.appendChild(spanEl)

        boxEl.appendChild(inpBox)
      }
    },
    // 右击菜单项点击
    onMenuClick(type) {
      if ((type !== 'addNext' && this.isRoot) || (this.curNodeInfo.busType === '06' && type === 'addNext')) {
        return false
      }
      this.$emit('menu-click', type, this.curNodeInfo)
    },
  },
}
</script>
<style lang="scss">
.tree-model-box {
  padding: 30px 20px;
  height: calc(100% - 66px);
  position: relative;
  overflow-y: auto;
  .index-model {
    width: auto;
    height: auto;
    .node-input-box {
      position: absolute;
      z-index: 99;
      display: flex;
      align-items: center;
      width: 140px;
      .inp-label {
        background: #e9eff4;
        height: 24px;
        line-height: 24px;
        font-size: 12px;
        width: 60px;
        padding: 0 5px;
        text-align: center;
      }
      .node-input {
        width: 60px;
        border: 1px solid #dcdfe6;
        height: 24px;
        padding: 0 5px;
        outline: none;
      }
      .unit {
        font-size: 12px;
        padding-left: 5px;
      }
    }
  }
  .right-menu {
    display: none;
    position: absolute;
    z-index: 99;
    box-shadow: 0px 0px 15px 0px rgba(2, 2, 2, 0.22);
    padding: 10px 0;
    background: #fff;
    .menu-box {
      width: 140px;
      .menu-item {
        font-size: 12px;
        padding: 0 10px;
        height: 28px;
        line-height: 28px;
        font-size: 12px;
        text-align: left;
        color: #666;
        cursor: pointer;
        &.disabled,
        &.disabled:hover,
        &.disabled:active {
          color: #d1d1d1;
          background-color: transparent;
          cursor: not-allowed;
        }
        &:hover,
        &:active {
          color: #409eff;
          background: #ecf5ff;
        }
      }
    }
  }
}
</style>
